#pragma once
namespace lh
{
	template<class T>
	class unique_ptr
	{
	public:
		unique_ptr(T* ptr = nullptr)
			:_ptr(ptr)
		{}
		~unique_ptr()
		{
			if (_ptr)
			{
				cout << "Delete:" << _ptr << endl;
				delete _ptr;
			}
		}
		unique_ptr(unique_ptr<T>& sp) = delete;
		unique_ptr<T>& operator=(unique_ptr<T>& sp) = delete;

		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
	};
	void test_unique_ptr()
	{
		lh::unique_ptr<int> sp1 = new int(1);
		lh::unique_ptr<int> sp2 = new int(2);
	}
	template<class T>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr=nullptr)
			:_ptr(ptr)
			,pCount(new int(1))
		{}
		void Release()
		{
			if (--(*pCount) == 0 )
			{
				cout << "Delete:" << _ptr << endl;
				delete _ptr;
				delete pCount;
			}
		}
		~shared_ptr()
		{
			Release();
		}
		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			,pCount(sp.pCount)
		{
			++(*pCount);
		}
		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			//自己和自己赋值
			if (_ptr == sp._ptr)
			{
				return *this;
			}
			//赋值前，先把之前管理的资源计数--
			Release();
			//赋值
			_ptr = sp._ptr;
			pCount = sp.pCount;
			++(*pCount);
			return *this;
		}
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
		//引用计数
		int* pCount;
	};
	class A {
	public:
		int _a1 = 0;
		int _a2 = 0;
	};
	void test_shared_ptr()
	{
		shared_ptr<int> sp1 (new int());
		shared_ptr<int>sp2(sp1);
		shared_ptr<A>sp3 (new A);
		shared_ptr<A>sp4 (new A);
		shared_ptr<A>sp5(sp3);
		sp5 = sp4;

	}
}